package com.zhai.boot.dao.mongo.base;

import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import com.zhai.boot.common.MongoConstant;
import com.zhai.boot.common.Page;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;

import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * @package: com.zhai.boot.dao.mongo.base
 * @project-name: zhai-boot
 * @description: mongo基础Dao实现
 * @author: Created by 翟凤玺
 * @create-datetime: 2018-8-7 11:20
 */
@Repository
public class BaseMongoDaoImpl<T> implements BaseMongoDao<T> {
    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 创建一个 Class 的对象来获取泛型的 Class
     */
    private Class<T> clz;

    public Class<T> getClz() {
        if (clz == null) {
            clz = ((Class<T>) (((ParameterizedType) (this.getClass().getGenericSuperclass())).getActualTypeArguments()[0]));
        }
        return clz;
    }

    @Override
    public T getById(String id) {
        Criteria criteria = Criteria.where(MongoConstant.ID).is(new ObjectId(id));
        Query query = new Query(criteria);
        return mongoTemplate.findOne(query, getClz());
    }

    @Override
    public Page gird(Integer pageNum, Integer pageSize) {
        pageNum = pageNum == null ? MongoConstant.DEFAULT_PAGE_NUM : pageNum;
        pageSize = pageSize == null ? MongoConstant.DEFAULT_PAGE_SIZE : pageSize;
        Query query = new Query();
        Long totalRows = mongoTemplate.count(query, getClz());
        query.skip((pageNum - 1) * pageSize).limit(pageSize);
        List<T> list = mongoTemplate.find(query, getClz());
        return Page.result(totalRows, pageNum, pageSize, list);
    }

    @Override
    public void insert(T t) {
        mongoTemplate.insert(t);
    }

    @Override
    public Boolean update(Update update, String id) {
        Criteria criteria = Criteria.where(MongoConstant.ID).is(new ObjectId(id));
        Query query = new Query(criteria);
        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, getClz());
        return updateResult.getMatchedCount() > 0 ? true : false;
    }

    @Override
    public Boolean remove(String id) {
        Criteria criteria = Criteria.where(MongoConstant.ID).is(new ObjectId(id));
        Query query = new Query(criteria);
        DeleteResult remove = mongoTemplate.remove(query, getClz());
        return remove.getDeletedCount() > 0 ? true : false;
    }
}
